/*
 * @(#)Storage.java	0.5 29/08/2009
 */
package com.ly.mpayment.persist.catstorage;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.Resource;

/**
 * 仓库猫框架的主控类，是其他程序调用框架功能的接口
 * 
 * 
 * @version 0.5
 * @since 0.1
 */
public class Storage {

	/**
	 * 预定义语句存储池
	 */
	private StatementPool pool;
	/**
	 * 过滤器
	 */
	private Filter filter;

	private Resource[] resource;
	private File[] file;
	/**
	 * 缓存容量
	 */
	private int capacity = 0;
	/**
	 * 是否使用缓存
	 */
	private boolean cache = false;
	/**
	 * 日志
	 */
	private static Log log = LogFactory.getLog(Storage.class);

	/**
	 * 缺省构造方法
	 * 
	 * @since 0.1
	 */
	public Storage() {
	}

	/**
	 * 根据资源文件resource构建Storage
	 * 
	 * @param resource
	 *            资源文件
	 * @since 0.2
	 */
	public Storage(Resource[] resource) {
        this.resource = resource;
        for(int i=0;i<resource.length;i++)
			try {
				this.file[i]=resource[i].getFile();
				log.info("加载HQL文件："+this.file[i].getPath());
			} catch (IOException e) {
				log.error("初始化失败:",e);
			}
    }

	/**
	 * 仓库猫框架初始化
	 * 
	 * @since 0.1
	 */
	public void config() {
		pool = new JsonStatementPool(this.file);
		pool.config();
		filter = new ClearFilter(new StatementFilter());
		setCache();
		log.info("仓库猫初始化完成");
	}

	/**
	 * 设置缓存
	 * 
	 * @since 0.5
	 */
	private void setCache() {
		if (cache) {
			Cache<String, String> statementCache = null;
			if (capacity > 0) {
				statementCache = new Cache<String, String>(capacity);
			} else {
				statementCache = new Cache<String, String>();
			}
			FilterCacheProxy proxy = new FilterCacheProxy(statementCache,
					filter);
			filter = proxy;
			log.info("缓存启动");
		}
	}

	/**
	 * 获得语句
	 * <p>
	 * 列表parameters记录了所有查询参数。程序会根据这些参数对预定义语句进行检查。
	 * 如果语句中的条件在参数中，则这些条件会被保留，不符合的条件会被删除。
	 * </p>
	 * 
	 * @param key
	 *            语句Key
	 * @param parameters
	 *            查询参数
	 * @return 处理结果
	 * @since 0.1
	 */
	public Result get(String key, List<String> parameters) {
		String result = filter(pool.get(key), parameters);
		if (result != null) {
			return new Result(result);
		} else {
			return null;
		}
	}

	/**
	 * 获得语句
	 * <p>
	 * Map对象parameters以参数名作为key，参数值作为value。程序会根据key和value对预定义语句进行检查。
	 * 如果语句中的条件在参数中且value有值（非null），则这些条件会被保留，不符合的条件会被删除。
	 * </p>
	 * 
	 * @param key
	 *            语句Key
	 * @param parameters
	 *            查询参数
	 * @return 处理结果
	 * @since 0.1
	 */
	public Result get(String hql, Map<String, Object> parameters) {
			return getResult(hql,(parameters));
	}
	 
//	//特殊标示符
//	private String keyString2 = ":REPLACE_HANDLE_TYPE";
//	private String keyString3 = ":REPLACE_HANDLE_STATUS";
//	//
//	
//	private Result getFindEvent(String key,Map<String, Object> parameters){
//		if(parameters.get(":type") != null && parameters.get(":type").toString().equals(keyString2)){
//			key = key.replace(keyString2, "and ff.type is null");
//			parameters.remove(":type");
//		}else {
//			key = key.replace(keyString2, "and ff.type = :type ");
//		}
//		if(parameters.get(":status") != null && parameters.get(":status").toString().equals(keyString3)){
//			key = key.replace(keyString3, "and ff.status is null");
//			parameters.remove(":status");
//		}else {
//			key = key.replace(keyString3, "and ff.status = :status");
//		}
//		return getResult(key,(parameters));
//	}
	
	private Result getResult(String sql,Map<String, Object> parameters){
		String result = filter(sql, getParameterList(parameters));
		if (result != null) {
			return new Result(result);
		} else {
			return null;
		}
	}

	/**
	 * 预定义语句过滤
	 * 
	 * @param statement
	 *            预定义语句
	 * @param parameters
	 *            查询参数
	 * @return 处理好的语句
	 * @since 0.2
	 */
	private String filter(String statement, List<String> parameters) {
		if (statement == null) {
			return null;
		} else {
			if (parameters == null) {
				parameters = new ArrayList<String>();
			}
			return filter.filter(statement, parameters);
		}
	}

	/**
	 * 根据参数Map生成参数列表
	 * 
	 * @param parameters
	 *            参数Map
	 * @return 参数列表
	 * @since 0.1
	 */
	private List<String> getParameterList(Map<String, Object> parameters) {
		Iterator<Entry<String, Object>> iterator = parameters.entrySet()
				.iterator();
		List<String> parameterList = new ArrayList<String>();
		while (iterator.hasNext()) {
			Entry<String, Object> entry = iterator.next();
			if (entry.getValue() != null) {
				parameterList.add(entry.getKey());
			}
		}
		return parameterList;
	}

	/**
	 * 设置语句存储池
	 * 
	 * @param pool
	 *            语句存储池
	 * @since 0.2
	 */
	public void setPool(StatementPool pool) {
		this.pool = pool;
	}

	/**
	 * 设置过滤器
	 * 
	 * @param filter
	 *            过滤器
	 * @since 0.2
	 */
	public void setFilter(Filter filter) {
		this.filter = filter;
	}


	 /**
     * 设置资源文件
     *
     * @param resource 资源文件
     * @since 0.2
     */
    public void setResource(Resource[] resource) {
        this.resource = resource;
        this.file=new File[this.resource.length];
        for(int i=0;i<resource.length;i++){
			try {
				this.file[i]=resource[i].getFile();
				log.info("HQL文件："+this.file[i].getPath()+" 加载完成");
			} catch (IOException e) {
				log.error("初始化失败:",e);
			}
        }
        if(this.resource.length <= 0){
        	log.info("仓库猫没有加载任何json文件！");
        }
    }

    /**
     * 获得资源文件
     *
     * @return 资源文件
     * @since 0.2
     */
    public Resource[] getResource() {
        return resource;
    }


	/**
	 * 设定缓存空间容量
	 * 
	 * @param capacity
	 *            缓存空间容量
	 * @since 0.5
	 */
	public void setCapacity(int capacity) {
		this.capacity = capacity;
	}

	/**
	 * 设定是否使用缓存
	 * 
	 * @param cache
	 *            是否使用缓存
	 * @since 0.5
	 */
	public void setCache(boolean cache) {
		this.cache = cache;
	}
}
